# coding=utf-8
import uuid
import hashlib
from django.contrib.auth.models import User, Group
from django.db import models
import time
from com.kjssoft.common.beehive.models import Goods
from com.kjssoft.common.globals import DBTableAssist
from com.kjssoft.common.models import ModelServerException
from com.kjssoft.eagleye.consts import UserProfileConsts, UserStatusConsts, EagleyeUserConsts

__author__ = 'daihaibin'

class UserProfileWrapper(object):
    @staticmethod
    def user_profile(initial=True, raised=True):
        """
        用户属性物品相关，goods_uuid -> UserGoods, goods model ->UserGoods
        @initial 当为true时，自动初始化用户物品
        @raised 当为true时，抛出ModelServerException 否者返回False
        """
        def profile_wrapper(profile_func):
            def _wrapper_profile_func(profile, profile_goods, *args, **kwargs):
                if profile_goods:
                    if isinstance(profile_goods, int) or isinstance(profile_goods, Goods):
                        #加载Goods对象
                        if isinstance(profile_goods,int):
                            try:
                                goods = Goods.objects.get(uuid = profile_goods)
                            except Goods.DoesNotExist as e:
                                if raised:
                                    raise ModelServerException('Available Goods definition required to set user profile goods. Exception refer %s.' % e)
                                else:
                                    return False
                        else:
                            goods = profile_goods
                        user_goods = UserGoods.objects.filter(
                            user = profile.user,
                            goods = profile_goods
                        )
                        if user_goods.count():
                            user_goods = user_goods[0]
                        else:
                            if initial:
                                user_goods = UserGoods.objects.create(
                                    user = profile.user,
                                    goods = goods,
                                    size = 0,
                                    value = None,
                                    add_ms = int(time.time())
                                )
                                user_goods.save()
                            else:
                                if raised:
                                    raise ModelServerException('Available Goods definition required to set user profile goods.')
                                else:
                                    return False
                    elif isinstance(profile_goods, UserGoods):
                        user_goods = profile_goods
                    else:
                        if raised:
                            raise ModelServerException('Available Goods definition required to set user profile goods.')
                        else:
                            return False
                    return profile_func(profile, user_goods, *args, **kwargs)
                else:
                    if raised:
                        raise ModelServerException('Available Goods definition required to set user profile goods.')
                    else:
                        return False
            return _wrapper_profile_func
        return profile_wrapper

class UserProfile(object):
    def __init__(self, user):
        if user and isinstance(user, EEUser):
            self.user = user
        else:
            raise TypeError('Just kjs eagleye user can be haven profile.')

    def _get_profile_nickname(self):
        return self._get_profile(UserProfileConsts.USER_PROFILE_NICKNAME)
    nickname = property(_get_profile_nickname)

    def _get_profile_snapshot(self):
        snapshot_profile = self._get_profile(UserProfileConsts.USER_PROFILE_SNAPSHOT)
        if not snapshot_profile:
            snapshot_profile = UserGoods.objects.create(
                user = self.user,
                goods = Goods.objects.get(uuid = UserProfileConsts.USER_PROFILE_SNAPSHOT),
                size = 1,
                value = 'default',
                add_ms = int(time.time())
            )
        return snapshot_profile
    snapshot = property(_get_profile_snapshot)

    @UserProfileWrapper.user_profile()
    def set_profile(self, profile_goods, size=1, value=None):
        """
        设置用户属性物品
        """
        profile_goods.size = size
        profile_goods.value = value
        profile_goods.add_ms = int(time.time())
        profile_goods.save()

    @UserProfileWrapper.user_profile(initial=False, raised=False)
    def _get_profile(self, profile_goods):
        return profile_goods

class EEUser(User):

    status = models.IntegerField(default=UserStatusConsts.STATUS_SET, choices=UserStatusConsts.status_choices())

    def _profile(self):
        return UserProfile(self)
    profile = property(_profile)

    def _social_binds(self):
        from com.kjssoft.eagleye.social.models import SocialUser
        return SocialUser.objects.filter(bind_user = self)
    binds = property(_social_binds)

    def initial(self, nickname):
        user = self
        default_user_group = Group.objects.get(name = EagleyeUserConsts.Group.DEFAULT_USER_GROUP_NAME)
        user.profile.set_profile(UserProfileConsts.USER_PROFILE_NICKNAME, value=nickname)
        user.groups.add(default_user_group)

    @classmethod
    def set_random_account(cls, nickname):
        random_username = '%s_%s_%s' % (
            str(uuid.uuid1()),
            'eeuser',
            'random'
        )
        md5 = hashlib.md5()
        md5.update(random_username)
        random_username = md5.hexdigest()
        user = cls.objects.create(
            username = random_username,
            password = random_username
        )
        user.set_password(random_username)
        user.save()
        user.initial(nickname)
        random_user_group = Group.objects.get(name = EagleyeUserConsts.Group.DEFAULT_USER_GROUP_NAME)
        user.groups.add(random_user_group)
        return user

    def get_json(self):
        value = {
            "uuid":self.id,
            "nickname":self.profile.nickname.value()
        }
        if self.profile.snapshot:
            value.update({"snapshot":self.profile.snapshot.value()})
        return

    class Meta:
        db_table = DBTableAssist.get_db_table_name('eagleye_user')

class UserGoods(models.Model):
    user   = models.ForeignKey(EEUser, related_name='user_goods_user')
    goods  = models.ForeignKey(Goods, related_name='user_goods_goods')
    size   = models.IntegerField()
    value  = models.CharField(max_length=255, null=True, blank=True)
    add_ms = models.IntegerField()

    class Meta:
        db_table = DBTableAssist.get_db_table_name('eagleye_user_goods')
